﻿using System;
using Noea.TogSim.Model.Interfaces;

namespace Noea.TogSim.Model.Tracks
{
    public class SwitchTrack : SimpleTrack, ITrack
    {
        public const int Right = 0;
        public const int Left = 1;
        int _direction;
        ITrack _rightTrack;
        ITrack _leftTrack;
        ITrack _trunkTrack;
        ITrack _next;
        ITrack _previous;

        SwitchTrack(int id)
            : base(id)
        { }
        public SwitchTrack(int id, bool blocked, int direction)
            : base(id, blocked)
        {
            Direction = direction;
        }
        public SwitchTrack(int id, bool blocked, double length, int direction)
            : base(id, blocked, length)
        {
            Direction = direction;
        }
        public SwitchTrack(int id, bool blocked, double length, ITrack next, ITrack prev, int direction)
            : base(id, blocked, length, next, prev)
        {
            Direction = direction;
        }
        public SwitchTrack(int id, bool blocked, double length, double angle, ITrack next, ITrack prev, int direction)
            : base(id, blocked, length, angle, next, prev)
        {
            Direction = direction;
        }
        public SwitchTrack(int id, bool blocked, double length, double angle, ITrack next, ITrack prev, ISignal sig, int direction)
            : base(id, blocked, length, angle, next, prev, sig)
        {
            Direction = direction;
        }


        public int Direction { get { return _direction; }
            set
            {
                if (!IsBlocked)
                {
                    int newValue = value;
                    int oldValue = _direction;

                    if (oldValue != newValue)
                    {
                        _direction = newValue;
                        FireChange(oldValue, newValue);
                    }
                }
                else
                {
                    throw (new Exception("Track is blocked. Direction is not changed"));
                }
            }
        }
        public ITrack RightTrack { get { return _rightTrack; } set { _rightTrack = value; } }
        public ITrack LeftTrack { get { return _leftTrack; } set { _leftTrack = value; } }
        public ITrack TrunkTrack { get { return _trunkTrack; } set { _trunkTrack = value; } }
        public override ITrack Next
        {
            get
            {
                if (_next == TrunkTrack) return _next;
                if (_direction == 0)
                {
                    return RightTrack;
                }
                else
                {
                    return LeftTrack;
                }
            }
            set
            { // Handle as a simple track
                _next = value;
                //if (_next == TrunkTrack) return _next;
                if (_direction == 0)
                {
                    RightTrack = value;
                }
                else
                {
                    LeftTrack = value;
                }
            }
        }
        public override ITrack[] NextList
        {
            get
            {
                ITrack[] result;
                if (Previous == TrunkTrack)
                {
                    ITrack[] a = { RightTrack, LeftTrack };
                    result = a;
                }
                else
                {
                    if (Previous == LeftTrack)
                    {
                        ITrack[] a = { TrunkTrack, RightTrack };
                        result = a;
                    }
                    else
                    {
                        ITrack[] a = { TrunkTrack, LeftTrack };
                        result = a;
                    }
                }
                return result;
            }
        }

        //public override ITrack Previous
        //{
        //    get
        //    {
        //        if (_previous == TrunkTrack) return _previous;
        //        if (_direction == 0)
        //        {
        //            return RightTrack;
        //        }
        //        else
        //        {
        //            return LeftTrack;
        //        }
        //    }
        //    set
        //    { // Handle as a simple track
        //        _previous = value;
        //    }
        //}

        public override ITrack GetNext(ITrack previousTrack)
        {
            //Console.WriteLine("id: {0}: TrunkTrack={1} og previousTrack={2}", this.Id, this.TrunkTrack.Id, previousTrack.Id);
            if (this.Next != this.TrunkTrack) return base.GetNext(previousTrack);
            if (previousTrack != this.TrunkTrack) return TrunkTrack;
            if (this.Direction == Left) return this.LeftTrack;
            return this.RightTrack;
        }

        public void Toggle()
        {
            Direction = Math.Abs(Direction - 1); //Uha, spidsfindighederne tager ingen ende!!
        }

        public override string ToString()
        {
            return base.ToString() + String.Format("\nTrunk: {0} Left: {1} Right: {2}", this.TrunkTrack, this.LeftTrack, this.RightTrack);
        }
    }
}
